#include "SCheckEx.h"
#include <core/StyleMgr.h>
#include <core/ImageMgr.h>
#include <QFontMetrics>
#include <QStylePainter>
#include <QPaintEvent>

SCheckEx::SCheckEx(const QString& v, QWidget* parent /*= nullptr*/)
	: QWidget(parent),m_text(v)
{

}

void SCheckEx::setSelectState(Qt::CheckState v, bool notify)
{
	m_selectState = v;
	update();
	if (notify)
		stateChanged(m_selectState);
}

QSize SCheckEx::sizeHint() const
{
	QSizePolicy policy = sizePolicy();
	if (policy.horizontalPolicy() == QSizePolicy::Expanding || policy.horizontalPolicy() == QSizePolicy::Fixed || policy.verticalPolicy() == QSizePolicy::Fixed )
		return QWidget::sizeHint();


	int gap = StyleMgr::instance().size("CtrlSpacing");
	int width = gap;
	SImage* img = ImgMgr::instance().image("widgets_check", WidgetStatus::kNormal, devicePixelRatioF());
	if (img)
		width += img->width() + gap;
	
	QFontMetrics fm(font());
	width += fm.horizontalAdvance(m_text) + gap;
	return QSize(width, StyleMgr::instance().size("ButtonHeight"));
}

void SCheckEx::mousePressEvent(QMouseEvent* e)
{
	if (m_selectState == Qt::Unchecked)
		m_selectState = Qt::Checked;
	else
	{
		if (m_type == SelectType::Radio)
			return;
		m_selectState = Qt::Unchecked;
	}
		

	update();
	stateChanged(m_index);
}

void SCheckEx::enterEvent(QEvent* event)
{
	m_hover = true;
	update();
}

void SCheckEx::leaveEvent(QEvent* event)
{
	m_hover = false;
	update();
}

void SCheckEx::paintEvent(QPaintEvent* event)
{
	QStylePainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);
	QColor bkColor = StyleMgr::instance().color("StaticTextBK");
	painter.setBrush(bkColor);
	painter.setPen(bkColor);
	painter.drawRoundedRect(rect(), StyleMgr::instance().size("RoundCorner"), StyleMgr::instance().size("RoundCorner"));

	QString imageName;
	switch (m_type)
	{
	case SCheckEx::SelectType::Check:
		imageName = m_selectState == Qt::Checked ? "widgets_check_selected" : "widgets_check";//TODO: PartiallyChecked
		break;
	case SCheckEx::SelectType::Radio:
		imageName = m_selectState == Qt::Checked ? "widgets_radio_selected" : "widgets_radio";
		break;
	case SCheckEx::SelectType::Switch:
		imageName = m_selectState == Qt::Checked ? "widgets_grid_remdon" : "widgets_grid_remdoff";
		break;
	default:
		break;
	}

	WidgetStatus status = isEnabled() ? (m_hover ? WidgetStatus::kHover : WidgetStatus::kNormal) : WidgetStatus::kDisabled;
	SImage* img = ImgMgr::instance().image(imageName, status, devicePixelRatioF());
	QRect indicatorRect = rect();
	if (img)
	{
		int width = img->width();
		int height = img->height();
		int y = (rect().height() - height) / 2;
		indicatorRect.setRect(StyleMgr::instance().size("CtrlSpacing"), y, width, height);

		painter.drawImage(indicatorRect, *img);
	}

	QRect txtrect = rect();
	txtrect.adjust(indicatorRect.right() + StyleMgr::instance().size("CtrlSpacing"), 0, 0, 0);
	QString txtColorName = isEnabled() ? (m_selectState == Qt::Unchecked ? "TextNormal" : "Highlight") : "TxtDisabled";
	if (m_type == SelectType::Check && !isEnabled() && m_selectState == Qt::Checked)
		txtColorName = "Highlight";
	QColor txtColor = StyleMgr::instance().color(txtColorName);
	painter.setPen(txtColor);
	painter.drawText(txtrect, m_text, QTextOption(Qt::AlignVCenter | Qt::AlignLeft));
}

SRadioGroup::SRadioGroup(QObject* p)
	: QObject(p)
{

}

void SRadioGroup::addRadio(SCheckEx* item)
{
	if (!item)
		return;
	int index = item->index();
	auto iter = m_items.find(index);
	Q_ASSERT(iter == m_items.end());
	m_items[index] = item;

	connect(item, &SCheckEx::stateChanged, this, &SRadioGroup::onRadioSelect);
}

void SRadioGroup::onRadioSelect(int index)
{
	auto iter = m_items.find(index);
	bool checked = iter->second->isSelected();
	if (!checked)
		return;
	for (auto iterFind = m_items.begin(); iterFind != m_items.end(); ++iterFind)
	{
		if(iterFind == iter)
			continue;
		iterFind->second->setSelectState(checked ? Qt::Unchecked : Qt::Checked);
	}
}
